/*! \file mem_allocator.inl
 *	\brief 
 *
 *	created:	2009/11/20
 *	created:	20:11:2009   18:34
 *	filename: 	o:\main\libs\mem\mem_allocator.inl
 *	file path:	o:\main\libs\mem
 *	file base:	mem_allocator
 *	file ext:	inl
 *	author:		Vitalii Trubchaninov
 *				venngraydog@gmail.com
 */
 
namespace tt{
namespace mem{

#if TT_MEM_ENABLED && TT_MEM_PROFILING

namespace impl{
	MEM_API BlockInfo* active_section();
	MEM_API void register_allocate(BlockInfo* block_info, std::size_t __n);
	MEM_API void register_deallocate(BlockInfo* block_info, std::size_t __n);
} //impl

#endif //TT_MEM_ENABLED && TT_MEM_PROFILING

template<class _Ty>
allocator<_Ty>::allocator( )
: m_allocator()
#if TT_MEM_ENABLED && TT_MEM_PROFILING
, m_section( impl::active_section() )
#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
{

}

template<class _Ty>
allocator<_Ty>::allocator(const allocator<_Ty>& _Right)
: m_allocator(_Right.m_allocator)
#if TT_MEM_ENABLED && TT_MEM_PROFILING
, m_section(_Right.m_section)
#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
{

}

template<class _Ty>
template<class Other>
allocator<_Ty>::allocator(const allocator<Other>& _Right)
: m_allocator(_Right.m_allocator)
#if TT_MEM_ENABLED && TT_MEM_PROFILING
, m_section(_Right.m_section)
#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
{

}

template<class _Ty>
template<class Other>
allocator<_Ty>& allocator<_Ty>::operator=(const allocator<Other>& _Right)
{
	m_allocator = _Right.m_allocator;
#if TT_MEM_ENABLED && TT_MEM_PROFILING
	m_section = _Right.m_section;
#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
	return *this;
}

template<class _Ty>
typename allocator<_Ty>::pointer allocator<_Ty>::address(reference _Val) const
{
	return m_allocator.address(_Val);
}

template<class _Ty>
typename allocator<_Ty>::const_pointer allocator<_Ty>::address(const_reference _Val) const
{
	return m_allocator.address(_Val);
}

template<class _Ty>
typename allocator<_Ty>::pointer allocator<_Ty>::allocate(size_type _Count, const void* _Hint)
{
	pointer _p = m_allocator.allocate(_Count, _Hint);
#if TT_MEM_ENABLED && TT_MEM_PROFILING
	if (_p)
		impl::register_allocate(m_section, _Count * sizeof(_Ty));
#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
	return _p;
}

template<class _Ty>
void allocator<_Ty>::construct(pointer _Ptr, const _Ty& _Val)
{
	m_allocator.construct(_Ptr, _Val);
}

template<class _Ty>
void allocator<_Ty>::deallocate(pointer _Ptr, size_type _Count)
{
#if TT_MEM_ENABLED && TT_MEM_PROFILING
	if(_Ptr)
		impl::register_deallocate(m_section, _Count * sizeof(_Ty));
#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
	m_allocator.deallocate(_Ptr, _Count);
}

template<class _Ty>
void allocator<_Ty>::destroy(pointer _Ptr)
{
	m_allocator.destroy(_Ptr);
}

template<class _Ty>
typename allocator<_Ty>::size_type allocator<_Ty>::max_size( ) const
{
	return m_allocator.max_size();
}

//////////////////////////////////////////////////////////////////////////
//Venn: STLPort needs this definitions for some reason!
template<class _Ty, class _Other>
bool operator==(const allocator<_Ty>&, const allocator<_Other>&)
{	// test for allocator equality (always true)
	return (true);
}

template<class _Ty, class _Other>
bool operator!=(const allocator<_Ty>&, const allocator<_Other>&)
{	// test for allocator inequality (always false)
	return (false);
}

} //namespace mem
} //namespace tt
